package com.hjc.qrcode.demos.web;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;

/**
 * @author hjc
 * @date 2024/4/17 8:35
 */
@Controller
@RequestMapping("/qrcode")
public class QRCodeController {
    //获取QRcode
    // http://127.0.0.1:8080/qrcode/create
    @RequestMapping("/create")
    public void getQRCode(HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        try {
            // 准备一个Map集合，用来存储二维码图片的相关属性
            Map map = new HashMap();

            //设置误差校验级别
            map.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);

            // 设置字符编码（因为文本内容要转换成二维码，需要指定转换时采用的字符集）
            map.put(EncodeHintType.CHARACTER_SET, "utf-8");

            //设置二维码外边距
            map.put(EncodeHintType.MARGIN, 1);

            //获取要生成二维码的文本内容
            String url = request.getParameter("url");

            //创建MultiFormatWriter对象，用于生成二维码
            MultiFormatWriter writer = new MultiFormatWriter();
            // 传入：内容、码的格式、宽度、高度、二维码参数。返回位矩阵对象。
            BitMatrix bitMatrix = writer.encode(url, BarcodeFormat.QR_CODE, 300, 300, map);
            //获取矩阵的高度和宽度
            int width = bitMatrix.getWidth();
            int height = bitMatrix.getHeight();

            // 创建一个BufferedImage对象，用于存储二维码图片
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            //遍历矩阵
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    // 获取矩阵中每个元素的颜色值
                    // RGB：黑色0x000000，白色0xFFFFFF
                    // ARGB:0xFF000000 黑色,0xFFFFFFFF 白色,最高的两个字节 0xFF 表示 alpha 通道的最大值（即完全不透明）
                    int color = bitMatrix.get(x, y) ? 0x000000 : 0xFFFFFF;
                    // 将颜色值赋给BufferedImage对象对应位置的颜色值
                    image.setRGB(x, y, color);
                }
            }

            // 响应
            ServletOutputStream out = response.getOutputStream();
            ImageIO.write(image, "png", out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
